/**
 * @file WordQueryServer.cpp
 * @author your name (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2022-04-05
 *
 * @copyright Copyright (c) 2022
 *
 */

#include "../include/network/TcpServer.h"
#include "../include/utils/Threadpool.h"
#include "../include/WordQuery.hpp"

#include <stdio.h>

#include <functional>
#include <string>

using namespace std;
using namespace wd;

class WordQueryServer
{
  public:
    WordQueryServer(const string &configfile);

    void start();

  private:
    void onConnection(const TcpConnectionPtr &conn);
    void onMessage(const TcpConnectionPtr &conn);
    void onClose(const TcpConnectionPtr &conn);
    void doTaskThread(const TcpConnectionPtr &conn, const string &msg);

  private:
    Configuration _conf;
    WordQuery _wordQuery;
    TcpServer _tcpServer;
    Threadpool _pool;
};

WordQueryServer::WordQueryServer(const string &configfile)
    : _conf(configfile), _wordQuery(_conf), _tcpServer(5080), _pool(4, 10)
{
    _tcpServer.setConnectionCallback(
        std::bind(&WordQueryServer::onConnection, this, placeholders::_1));
    _tcpServer.setMessageCallback(
        std::bind(&WordQueryServer::onMessage, this, placeholders::_1));
    _tcpServer.setCloseCallback(
        std::bind(&WordQueryServer::onClose, this, placeholders::_1));
}

void WordQueryServer::start()
{
    _pool.start();
    _tcpServer.start();
}

void WordQueryServer::onConnection(const TcpConnectionPtr &conn)
{
    printf("%s\n", conn->toString().c_str());
}

void WordQueryServer::onMessage(const TcpConnectionPtr &conn)
{
    string msg(conn->receive());
    size_t pos = msg.find('\n');
    msg = msg.substr(0, pos);
    cout << "client:" << msg << ",size:" << msg.size() << endl;

    // string ret = _wordQuery.doQuery(msg);
    // cout << "result's size:" << ret.size() << endl;
    // conn->send(ret);

    _pool.addTask(std::bind(&WordQueryServer::doTaskThread, this, conn, msg));
}

void WordQueryServer::onClose(const TcpConnectionPtr &conn)
{
    printf("%s close.\n", conn->toString().c_str());
}

void WordQueryServer::doTaskThread(const TcpConnectionPtr &conn, const string &msg)
{
    string ret = _wordQuery.doQuery(msg);

    int sz = ret.size();
    printf("result's size:%d\n", sz);
    // printf("%s\n\n", ret.c_str());
    // string slength((const char *)&sz, 4);

    string message(to_string(sz));
    message.append("\n").append(ret);
    // printf("message's size:%d\n",message.size());
    // conn->sendInLoop(slength);

    conn->sendInLoop(message);
}

int main(void)
{
    WordQueryServer wordQueryServer("./conf/my.conf");
    wordQueryServer.start();

    return 0;
}
